<template>
  <div :class="`preview ${scaleType}`">
    <template v-if="showEntity">
      <!-- 实体区域 -->
      <div
        ref="entityRef"
        class="preview__entity"
      >
        <!-- 缩放层 -->
        <div
          ref="previewRef"
          class="preview__scale"
        >
          <!-- 展示层 -->
          <div :style="previewRefStyle">
            <!-- 渲染层 -->
            <slot></slot>
          </div>
        </div>
      </div>
    </template>
    <template v-else>
      <!-- 缩放层 -->
      <div
        ref="previewRef"
        class="preview__scale"
      >
        <!-- 展示层 -->
        <div
          :style="previewRefStyle"
          class="preview_box"
        >
          <!-- 渲染层 -->
          <slot></slot>
        </div>
      </div>
    </template>
  </div>
</template>

<script>
export default {
  name: 'ScreenAdapter',
  props: {
    scaleType: {
      type: String,
      default: 'fit' // fit scrollY
    },
    width: {
      type: String,
      default: '1920'
    },
    height: {
      type: String,
      default: '1080'
    },
    bgColor: {
      type: String,
      default: ''
    }
  },
  computed: {
    showEntity() {
      return this.scaleType == 'scrollY'
    },
    previewRefStyle() {
      return {
        position: 'relative',
        width: `${this.width}px`,
        height: `${this.height}px`
      }
    }
  },
  mounted() {
    this.usePreviewScrollYScale()
    window.addEventListener('resize', this.usePreviewScrollYScale)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.usePreviewScrollYScale)
  },
  methods: {
    usePreviewScrollYScale() {
      const baseWidth = this.width
      const baseHeight = this.height
      // * 默认缩放值
      const scale = {
        width: 1,
        height: 1
      }
      // * 需保持的比例
      const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
      scale.height = parseFloat((window.innerWidth / baseProportion / baseHeight).toFixed(5))
      scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5))

      this.$refs.previewRef.style.transform = `scale(${scale.width}, ${scale.height})`
      this.$refs.entityRef.style.width = `${baseWidth * scale.width}px`
      this.$refs.entityRef.style.height = `${baseHeight * scale.height}px`
    }
  }
}
</script>
<style lang="scss" scoped>
.preview {
  position: relative;
  height: 100vh;
  width: 100vw;
  background: v-bind(bgColor);
  &.fit {
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    .preview__scale {
      transform-origin: center center;
    }
  }
  &.scrollY {
    overflow-x: hidden;
    .preview__scale {
      transform-origin: left top;
    }
  }
  &.fill {
    height: 100%;
    .preview__scale {
      height: 100%;
      transform-origin: center center;
    }
    .preview_box {
      height: 100% !important;
    }
  }
  &__entity {
    overflow: hidden;
  }
}
</style>
